using System;
using System.Text;

namespace RBAC.Read.Api.Utils
{
    /// <summary>
    /// 文件名帮助类，用于安全地生成HTTP响应头中的文件名
    /// </summary>
    public static class FileNameHelper
    {
        /// <summary>
        /// 生成安全的文件名（用于HTTP响应头）
        /// </summary>
        /// <param name="prefix">文件名前缀</param>
        /// <param name="extension">文件扩展名</param>
        /// <returns>安全的文件名</returns>
        public static string GenerateSafeFileName(string prefix, string extension)
        {
            var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            return $"{prefix}_{timestamp}.{extension.TrimStart('.')}";
        }

        /// <summary>
        /// 生成显示文件名（包含中文，用于用户界面）
        /// </summary>
        /// <param name="prefix">文件名前缀</param>
        /// <param name="extension">文件扩展名</param>
        /// <returns>显示文件名</returns>
        public static string GenerateDisplayFileName(string prefix, string extension)
        {
            var dateStr = DateTime.Now.ToString("yyyy年MM月dd日");
            return $"{prefix}_{dateStr}.{extension.TrimStart('.')}";
        }

        /// <summary>
        /// 生成RFC 5987兼容的Content-Disposition头值
        /// </summary>
        /// <param name="safeFileName">安全的文件名（ASCII字符）</param>
        /// <param name="displayFileName">显示文件名（可包含中文）</param>
        /// <returns>Content-Disposition头值</returns>
        public static string GenerateContentDisposition(string safeFileName, string displayFileName)
        {
            // 使用RFC 5987标准处理文件名编码
            var encodedFileName = Uri.EscapeDataString(displayFileName);
            return $"attachment; filename=\"{safeFileName}\"; filename*=UTF-8''{encodedFileName}";
        }

        /// <summary>
        /// 生成发货通知单的文件名
        /// </summary>
        /// <returns>文件名元组（安全文件名，显示文件名）</returns>
        public static (string SafeFileName, string DisplayFileName) GenerateDeliveryNoticeFileName()
        {
            var safeFileName = GenerateSafeFileName("DeliveryNotice", "xlsx");
            var displayFileName = GenerateDisplayFileName("发货通知单", "xlsx");
            return (safeFileName, displayFileName);
        }

        /// <summary>
        /// 生成销售订单的文件名
        /// </summary>
        /// <returns>文件名元组（安全文件名，显示文件名）</returns>
        public static (string SafeFileName, string DisplayFileName) GenerateSalesOrderFileName()
        {
            var safeFileName = GenerateSafeFileName("SalesOrder", "xlsx");
            var displayFileName = GenerateDisplayFileName("销售订单", "xlsx");
            return (safeFileName, displayFileName);
        }

        /// <summary>
        /// 生成供应商列表的文件名
        /// </summary>
        /// <returns>文件名元组（安全文件名，显示文件名）</returns>
        public static (string SafeFileName, string DisplayFileName) GenerateSupplierFileName()
        {
            var safeFileName = GenerateSafeFileName("Suppliers", "xls");
            var displayFileName = GenerateDisplayFileName("供应商列表", "xls");
            return (safeFileName, displayFileName);
        }

        /// <summary>
        /// 生成开票通知明细的文件名
        /// </summary>
        /// <returns>文件名元组（安全文件名，显示文件名）</returns>
        public static (string SafeFileName, string DisplayFileName) GenerateBillingNoticeFileName()
        {
            var safeFileName = GenerateSafeFileName("BillingNotice", "xlsx");
            var displayFileName = GenerateDisplayFileName("开票通知明细", "xlsx");
            return (safeFileName, displayFileName);
        }

        /// <summary>
        /// 验证文件名是否安全（只包含ASCII字符）
        /// </summary>
        /// <param name="fileName">要验证的文件名</param>
        /// <returns>是否安全</returns>
        public static bool IsSafeFileName(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return false;

            foreach (char c in fileName)
            {
                if (c > 127) // 非ASCII字符
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 清理文件名中的不安全字符
        /// </summary>
        /// <param name="fileName">原始文件名</param>
        /// <returns>清理后的文件名</returns>
        public static string SanitizeFileName(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return string.Empty;

            var invalidChars = System.IO.Path.GetInvalidFileNameChars();
            var sanitized = fileName;

            foreach (char invalidChar in invalidChars)
            {
                sanitized = sanitized.Replace(invalidChar, '_');
            }

            // 移除或替换非ASCII字符
            var sb = new StringBuilder();
            foreach (char c in sanitized)
            {
                if (c <= 127) // ASCII字符
                {
                    sb.Append(c);
                }
                else
                {
                    sb.Append('_');
                }
            }

            return sb.ToString();
        }
    }
} 